package io.jpress.commons.word;

import com.jfinal.core.JFinal;
import io.jboot.utils.FileUtil;
import io.jboot.utils.StrUtil;
import io.jboot.web.attachment.AttachmentManager;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Base64;

class DocumentUtil {


    /**
     * 主要是用于处理以下几个方面
     * 1、base64 图片本地化
     * 2、移除 word 页码区域
     * 3、匹配 html head 里定义的样式添加到元素里
     * 4、移除跟节点的 width css 属性
     *
     * @param documentString
     * @param cssElements
     * @return
     */
    public static String process(String documentString, String[] cssElements) {
        Document document = Jsoup.parse(documentString);
        Elements imgElements = document.select("img");

        for (Element imgElement : imgElements) {
            String src = imgElement.attr("src");
            if (StrUtil.isBlank(src)) {
                imgElement.remove();
                continue;
            }

            //png
            if (src.startsWith("data:image/png;base64,")) {
                src = base64ToImage(src.substring(22), ".png");
                imgElement.attr("src", src);
            }
            //jpeg
            else if (src.startsWith("data:image/jpeg;base64,")) {
                src = base64ToImage(src.substring(23), ".jpeg");
                imgElement.attr("src", src);
            }
            //jpg
            else if (src.startsWith("data:image/jpg;base64,")) {
                src = base64ToImage(src.substring(22), ".jpg");
                imgElement.attr("src", src);
            }
            //other jpg
            else if (src.startsWith("data:") && src.indexOf("base64,") > 0) {
                src = base64ToImage(src.split(",")[1], ".jpg");
                imgElement.attr("src", src);
            }
        }

        //页码区域
        Elements sdfields = document.select("sdfield");
        for (Element sdfield : sdfields) {
            sdfield.remove();
        }

        Elements sapapos = document.select("sapapo");
        for (Element sapapo : sapapos) {
            sapapo.remove();
        }

        String[] cssLines = null;
        Elements children = document.head().children();
        for (Element child : children) {
            if ("style".equals(child.tagName())) {
                String text = child.html();
                if (StrUtil.isNotBlank(text)) {
                    cssLines = text.split("\n");
                }
            }
        }

        if (cssLines != null && cssLines.length > 0 && cssElements != null && cssElements.length > 0) {
            for (String cssElement : cssElements) {
                Elements selectElemments = document.select(cssElement);
                for (Element selectElemment : selectElemments) {
                    String eleClassesString = selectElemment.className();
                    String[] eleClasses = eleClassesString.split(" ");
                    for (String eleClass : eleClasses) {
                        if (StrUtil.isNotBlank(eleClass)) {
                            String classStyleText = getClassStyleText(selectElemment.tagName(), eleClass.trim(), cssLines);
                            if (StrUtil.isNotBlank(classStyleText)) {
                                String currentStyle = selectElemment.attr("style");
                                if (StrUtil.isNotBlank(currentStyle)) {
                                    classStyleText += currentStyle;
                                }
                                selectElemment.attr("style", classStyleText);
                                selectElemment.removeAttr("class");
                            }
                        }
                    }
                }
            }
        }


        //移除 根标签 里的 style 的 width 属性
        Elements rootEles = document.body().children();
        for (Element rootEle : rootEles) {
            // style="margin:90.7pt 70.85pt;width:595.3pt;"
            String style = rootEle.attr("style");
            if (StrUtil.isNotBlank(style)) {
                int indexOf = style.indexOf("width:");
                if (indexOf > -1) {
                    int endIndexOf = style.indexOf(";", indexOf);
                    if (endIndexOf > indexOf) {
                        String newStyle = style.substring(0, indexOf) + style.substring(endIndexOf + 1);
                        rootEle.attr("style", newStyle);
                    }
                }
            }
        }

        //跟节点有 div 包裹，则移除 div
        if (document.body().childrenSize() == 1) {
            Element child = document.body().child(0);
            if ("div".equalsIgnoreCase(child.tagName())) {
                return child.html();
            }
        }


        return document.body().html();

    }


    private static String getClassStyleText(String tagName, String eleClass, String[] cssLines) {
        if (StrUtil.isBlank(eleClass)) {
            return null;
        }

        // tagName.eleClass
        for (String cssLine : cssLines) {
            int i = cssLine.indexOf(tagName + "." + eleClass);

            int i1 = cssLine.indexOf("{");
            int i2 = cssLine.indexOf("}");

            if (i >= 0 && i1 > i && i2 > i1) {
                return cssLine.substring(i1 + 1, i2);
            }
        }


        //.eleClass only
        for (String cssLine : cssLines) {
            int i = cssLine.indexOf("." + eleClass);

            int i1 = cssLine.indexOf("{");
            int i2 = cssLine.indexOf("}");

            if (i >= 0 && i1 > i && i2 > i1) {
                return cssLine.substring(i1 + 1, i2);
            }
        }

        return null;
    }


    private static String base64ToImage(String base64, String suffix) {
        File imageFile = AttachmentManager.me().createNewFile(suffix);
        OutputStream outStream = null;
        try {
            FileUtil.ensuresParentExists(imageFile);
            outStream = new FileOutputStream(imageFile);
//            byte[] bytes = new BASE64Decoder().decodeBuffer(base64);
            byte[] bytes = Base64.getMimeDecoder().decode(base64);
//            Base64.
//            BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(bytes));
//            ImageIO.write(bufferedImage,suffix.substring(1),outStream);
//            for (int i = 0; i < bytes.length; i++) {
//                bytes[i] += 256;
//            }
            outStream.write(bytes);
            outStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (outStream != null) {
                try {
                    outStream.close();
                } catch (IOException e) {
                }
            }
        }

        return JFinal.me().getContextPath() + AttachmentManager.me().getRelativePath(imageFile);
    }
}
